Perform shocks of ETH price to test controller parameter stability, without stochastic processes.
experiments/system_model_v3/experiment_shocks.py# Set project root folder, to enable importing project files from subdirectories
from pathlib import Path
import os
path = Path().resolve()
root_path = str(path).split('notebooks')[0]
os.chdir(root_path)
# Force reload of project modules, sometimes necessary for Jupyter kernel
%load_ext autoreload
%autoreload 2
# Display framework versions for easy debugging
%pip show cadCAD
%pip show radcad
Name: cadCAD Version: 0.4.23 Summary: cadCAD: a differential games based simulation software package for research, validation, and Computer Aided Design of economic systems Home-page: https://github.com/cadCAD-org/cadCAD Author: Joshua E. Jodesty Author-email: joshua@block.science License: LICENSE.txt Location: /home/bscholtz/workspace/reflexer/venv/lib/python3.8/site-packages Requires: fn, funcy, pandas, pathos Required-by: Note: you may need to restart the kernel to use updated packages. Name: radcad Version: 0.5.4 Summary: A cadCAD implementation, for dynamical systems modelling & simulation Home-page: None Author: Benjamin Scholtz Author-email: ben@bitsofether.com License: None Location: /home/bscholtz/workspace/reflexer/venv/lib/python3.8/site-packages Requires: tables, pathos, boto3, ray, pandas Required-by: Note: you may need to restart the kernel to use updated packages.
# Import all shared dependencies and setup
from shared import *
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# import plotly.io as pio
# pio.renderers.default = "png"
from pprint import pprint
# Update dataframe display settings
pd.set_option('display.max_columns', 100)
pd.set_option('display.max_rows', 50)
Using the experiment logs, select the experiment of interest from the specific HDF5 store file (these datasets are very large, and won't be committed to repo):
# experiment_results = 'experiments/system_model_v3/experiment_controller_sweep/experiment_results.hdf5'
experiment_results = 'experiments/system_model_v3/experiment_shocks/experiment_results.hdf5'
experiment_results_keys = []
with pd.HDFStore(experiment_results) as store:
experiment_results_keys = list(filter(lambda x: "results" in x, store.keys()))
exceptions_keys = list(filter(lambda x: "exceptions" in x, store.keys()))
# A list of all experiment result keys
experiment_results_keys
['/processed_results_2021-02-08T19:20:25.053328', '/processed_results_2021-02-08T19:45:15.538863', '/processed_results_2021-02-08T20:05:35.827550', '/processed_results_2021-02-08T22:54:43.005952', '/processed_results_2021-02-08T23:20:54.834451', '/results_2021-02-08T19:11:14.829535', '/results_2021-02-08T19:20:25.053328', '/results_2021-02-08T19:45:15.538863', '/results_2021-02-08T20:05:35.827550', '/results_2021-02-08T22:54:43.005952', '/results_2021-02-08T23:20:54.834451', '/results_2021-02-09T09:43:01.154807']
# A list of all experiment result exception keys
exceptions_keys
['/exceptions_2021-02-08T19:11:14.829535', '/exceptions_2021-02-08T19:20:25.053328', '/exceptions_2021-02-08T19:45:15.538863', '/exceptions_2021-02-08T20:05:35.827550', '/exceptions_2021-02-08T22:54:43.005952', '/exceptions_2021-02-08T23:20:54.834451', '/exceptions_2021-02-09T09:43:01.154807']
# Copy a results_ key from the above keys to select the experiment
experiment_results_key = 'results_2021-02-09T09:43:01.154807' # Or select last result: experiment_results_keys[-1]
experiment_timestamp = experiment_results_key.strip('results_')
exceptions_key = 'exceptions_' + experiment_timestamp
experiment_timestamp
'2021-02-09T09:43:01.154807'
df_raw = pd.read_hdf(experiment_results, experiment_results_key)
df_raw.tail()
| cdp_metrics | optimal_values | sim_metrics | timedelta | cumulative_time | timestamp | blockheight | eth_price | liquidity_demand | liquidity_demand_mean | cdps | eth_collateral | eth_locked | eth_freed | eth_bitten | principal_debt | rai_drawn | rai_wiped | rai_bitten | accrued_interest | interest_dripped | interest_wiped | interest_bitten | w_1 | w_2 | w_3 | system_revenue | stability_fee | market_price | market_price_twap | target_price | target_rate | eth_return | eth_gross_return | expected_market_price | expected_debt_price | error_star | error_star_integral | secondary_market_slippage | RAI_balance | ETH_balance | UNI_supply | uniswap_oracle | simulation | subset | run | substep | timestep | events | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 769414 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3589200 | 2017-02-11 13:00:00 | 0 | 300.0 | 0.0 | 7.466109e-301 | open time locked drawn ... | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584718e+07 | 2.684323e+07 | 1.099606e+07 | 0.0 | 7887.068526 | 0 | 0 | 0 | 0.000165 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283732 | 1.284012 | 0.863091 | -5.068893e-09 | 0.0 | 1.0 | 1.32113 | 3.14 | -0.032507 | -34660.235438 | 0 | 1.584747e+07 | 67810.507448 | 10000000.0 | <models.system_model_v3.model.parts.uniswap_or... | 0 | 8 | 5 | 14 | 997 | NaN |
| 769415 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3589200 | 2017-02-11 13:00:00 | 0 | 300.0 | 0.0 | 7.466109e-301 | open time locked drawn ... | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584718e+07 | 2.684352e+07 | 1.099606e+07 | 0.0 | 7887.068526 | 0 | 0 | 0 | 0.000165 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283732 | 1.284012 | 0.863091 | -5.068893e-09 | 0.0 | 1.0 | 1.32113 | 3.14 | -0.032507 | -34660.235438 | 0 | 1.584747e+07 | 67810.507448 | 10000000.0 | <models.system_model_v3.model.parts.uniswap_or... | 0 | 8 | 5 | 15 | 997 | NaN |
| 769416 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3589200 | 2017-02-11 13:00:00 | 0 | 300.0 | 0.0 | 7.466109e-301 | open time locked drawn ... | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584747e+07 | 2.684352e+07 | 1.099606e+07 | 0.0 | 7887.068526 | 0 | 0 | 0 | 0.000165 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283732 | 1.284012 | 0.863091 | -5.068893e-09 | 0.0 | 1.0 | 1.32113 | 3.14 | -0.032507 | -34660.235438 | 0 | 1.584747e+07 | 67810.507448 | 10000000.0 | <models.system_model_v3.model.parts.uniswap_or... | 0 | 8 | 5 | 16 | 997 | NaN |
| 769417 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3589200 | 2017-02-11 13:00:00 | 0 | 300.0 | 0.0 | 7.466109e-301 | open time locked drawn ... | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584747e+07 | 2.684352e+07 | 1.099606e+07 | 0.0 | 7887.068526 | 0 | 0 | 0 | 0.000165 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283732 | 1.284012 | 0.863091 | -5.068893e-09 | 0.0 | 1.0 | 1.32113 | 3.14 | -0.032507 | -34660.235438 | 0 | 1.584747e+07 | 67810.507448 | 10000000.0 | <models.system_model_v3.model.parts.uniswap_or... | 0 | 8 | 5 | 17 | 997 | NaN |
| 769418 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3589200 | 2017-02-11 13:00:00 | 0 | 300.0 | 0.0 | 7.466109e-301 | open time locked drawn ... | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584747e+07 | 2.684352e+07 | 1.099606e+07 | 0.0 | 7887.068526 | 0 | 0 | 0 | 0.000165 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283732 | 1.284012 | 0.863091 | -5.068893e-09 | 0.0 | 1.0 | 1.32113 | 3.14 | -0.032507 | -34660.235438 | 0 | 1.584747e+07 | 67810.507448 | 10000000.0 | <models.system_model_v3.model.parts.uniswap_or... | 0 | 8 | 5 | 18 | 997 | NaN |
Get experiment exceptions, tracebacks, and simulation metadata for further analysis:
exceptions_df = pd.read_hdf(experiment_results, exceptions_key)
exceptions_df.head()
| exception | traceback | simulation | run | subset | timesteps | parameters | initial_state | |
|---|---|---|---|---|---|---|---|---|
| 0 | underflow encountered in double_scalars | Traceback (most recent call last):\n File "/h... | 0 | 0 | 0 | 1440 | {"0":{"debug":false,"raise_on_assert":true,"fr... | {'cdp_metrics': {}, 'optimal_values': {}, 'sim... |
| 1 | underflow encountered in double_scalars | Traceback (most recent call last):\n File "/h... | 0 | 0 | 1 | 1440 | {"0":{"debug":false,"raise_on_assert":true,"fr... | {'cdp_metrics': {}, 'optimal_values': {}, 'sim... |
| 2 | underflow encountered in double_scalars | Traceback (most recent call last):\n File "/h... | 0 | 0 | 2 | 1440 | {"0":{"debug":false,"raise_on_assert":true,"fr... | {'cdp_metrics': {}, 'optimal_values': {}, 'sim... |
| 3 | underflow encountered in double_scalars | Traceback (most recent call last):\n File "/h... | 0 | 0 | 3 | 1440 | {"0":{"debug":false,"raise_on_assert":true,"fr... | {'cdp_metrics': {}, 'optimal_values': {}, 'sim... |
| 4 | underflow encountered in double_scalars | Traceback (most recent call last):\n File "/h... | 0 | 0 | 4 | 1440 | {"0":{"debug":false,"raise_on_assert":true,"fr... | {'cdp_metrics': {}, 'optimal_values': {}, 'sim... |
# Print the first 5 exceptions - indicating failed simulations
pprint(list(exceptions_df['exception'])[:5])
[FloatingPointError('underflow encountered in double_scalars'),
FloatingPointError('underflow encountered in double_scalars'),
FloatingPointError('underflow encountered in double_scalars'),
FloatingPointError('underflow encountered in double_scalars'),
FloatingPointError('underflow encountered in double_scalars')]
from experiments.system_model_v3.post_process import post_process_results
from experiments.system_model_v3.experiment_shocks import params, SIMULATION_TIMESTEPS
* Number of timesteps: 1440 / 60.0 days
* Timestep duration: 0.004 seconds
* Control parameters: ['kp', 'ki']
* Approx. number of values per parameter: 3
* Number of parameter combinations: 9
* Expected experiment duration: 0.8640000000000001 minutes / 0.014400000000000001 hours
Remove substeps, add set_params to dataframe, and add post-processing columns:
df = post_process_results(df_raw, params, set_params=['ki', 'kp', 'liquidation_ratio'])
df
| index | cdp_metrics | optimal_values | sim_metrics | timedelta | cumulative_time | timestamp | blockheight | eth_price | liquidity_demand | liquidity_demand_mean | cdps | eth_collateral | eth_locked | eth_freed | eth_bitten | principal_debt | rai_drawn | rai_wiped | rai_bitten | accrued_interest | interest_dripped | interest_wiped | interest_bitten | w_1 | w_2 | w_3 | system_revenue | stability_fee | market_price | market_price_twap | target_price | target_rate | eth_return | eth_gross_return | expected_market_price | expected_debt_price | error_star | error_star_integral | secondary_market_slippage | RAI_balance | ETH_balance | UNI_supply | uniswap_oracle | simulation | subset | run | substep | timestep | events | eth_collateral_value | collateralization_ratio | ki | kp | liquidation_ratio | target_price_scaled | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | {} | {} | {} | 0 | 0 | 2017-01-01 00:00:00 | 0 | 294.069151 | 1.0 | 1.000000e+00 | None | 154827.528922 | 154827.528922 | 0.000000 | 0.0 | 1.000000e+07 | 1.000000e+07 | 0.000000e+00 | 0.0 | 0.000000 | 0 | 0 | 0 | 0.000000e+00 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 3.140000 | 0.000000 | 3.140000 | 0.000000e+00 | 0.000000 | 0.0 | 3.140000 | 3.14 | 0.000000 | 0.000000 | 0 | 1.000000e+07 | 106777.606153 | 10000000.0 | None | 0 | 0 | 1 | 0 | 0 | NaN | 4.553000e+07 | 1.450000 | -1.000000e-09 | 1.000000e-07 | 1.45 | 4.553000 |
| 1 | 18 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3600 | 2017-01-01 01:00:00 | 0 | 300.000000 | 0.0 | 5.000000e-01 | None | 154827.528922 | 154827.528922 | 0.000000 | 0.0 | 1.450000e+07 | 1.450000e+07 | 0.000000e+00 | 0.0 | 5.707764 | 0 | 0 | 0 | 8.276258e+00 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 3.140000 | 0.000000 | 2.165517 | 0.000000e+00 | 0.020168 | 1.0 | 3.231683 | 3.14 | 3.140000 | 5652.000000 | 0 | 1.450000e+07 | 73708.353400 | 10000000.0 | None | 0 | 0 | 1 | 18 | 1 | NaN | 4.644826e+07 | 1.479244 | -1.000000e-09 | 1.000000e-07 | 1.45 | 3.140000 |
| 2 | 36 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 7200 | 2017-01-01 02:00:00 | 0 | 300.000000 | -0.0 | 2.500000e-01 | None | 105925.122117 | 154827.528922 | 48902.406805 | 0.0 | 1.012023e+07 | 1.450000e+07 | 4.379765e+06 | 0.0 | 11.484158 | 0 | 0 | 0 | 4.723892e-06 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.525000 | 0.000000 | 2.165517 | 0.000000e+00 | 0.000000 | 1.0 | 1.569093 | 3.14 | 3.140000 | 16932.000000 | 0 | 1.012023e+07 | 105703.331685 | 10000000.0 | None | 0 | 0 | 1 | 18 | 2 | NaN | 3.177754e+07 | 1.450000 | -1.000000e-09 | 1.000000e-07 | 1.45 | 3.140000 |
| 3 | 54 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 10800 | 2017-01-01 03:00:00 | 0 | 300.000000 | 0.0 | 1.250000e-01 | None | 105925.122117 | 154827.528922 | 48902.406805 | 0.0 | 1.012023e+07 | 1.450000e+07 | 4.379765e+06 | 0.0 | 17.260556 | 0 | 0 | 0 | 2.696510e-12 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 3.133425 | 0.000000 | 2.165517 | 0.000000e+00 | 0.000000 | 1.0 | 3.224303 | 3.14 | 3.140000 | 28166.000000 | 0 | 1.012023e+07 | 105703.331685 | 10000000.0 | None | 0 | 0 | 1 | 18 | 3 | NaN | 3.177754e+07 | 1.450000 | -1.000000e-09 | 1.000000e-07 | 1.45 | 3.140000 |
| 4 | 72 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 14400 | 2017-01-01 04:00:00 | 0 | 300.000000 | -0.0 | 6.250000e-02 | None | 105925.122117 | 154827.528922 | 48902.406805 | 0.0 | 1.012023e+07 | 1.450000e+07 | 4.379765e+06 | 0.0 | 23.036956 | 0 | 0 | 0 | 0.000000e+00 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 3.133425 | 0.000000 | 2.165517 | 0.000000e+00 | 0.000000 | 1.0 | 3.224444 | 3.14 | 3.140000 | 39354.000000 | 0 | 1.012023e+07 | 105703.331685 | 10000000.0 | None | 0 | 0 | 1 | 18 | 4 | NaN | 3.177754e+07 | 1.450000 | -1.000000e-09 | 1.000000e-07 | 1.45 | 3.140000 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 42783 | 769346 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3574800 | 2017-02-11 09:00:00 | 0 | 300.000000 | 0.0 | 1.194577e-299 | None | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584631e+07 | 2.684237e+07 | 1.099606e+07 | 0.0 | 7850.870783 | 0 | 0 | 0 | 1.645057e-04 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283918 | 1.284291 | 0.863154 | -5.059519e-09 | 0.000000 | 1.0 | 1.321322 | 3.14 | -0.032695 | -34764.662660 | 0 | 1.584631e+07 | 67815.435562 | 10000000.0 | None | 0 | 8 | 5 | 18 | 993 | NaN | 1.983318e+07 | 1.450026 | -1.000000e-07 | 1.000000e-05 | 1.45 | 1.251573 |
| 42784 | 769364 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3578400 | 2017-02-11 10:00:00 | 0 | 300.000000 | 0.0 | 5.972887e-300 | None | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584660e+07 | 2.684266e+07 | 1.099606e+07 | 0.0 | 7859.919964 | 0 | 0 | 0 | 1.647442e-04 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283872 | 1.284151 | 0.863138 | -5.059519e-09 | 0.000000 | 1.0 | 1.321274 | 3.14 | -0.032578 | -34738.492828 | 0 | 1.584660e+07 | 67814.204070 | 10000000.0 | None | 0 | 8 | 5 | 18 | 994 | NaN | 1.983318e+07 | 1.450026 | -1.000000e-07 | 1.000000e-05 | 1.45 | 1.251550 |
| 42785 | 769382 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3582000 | 2017-02-11 11:00:00 | 0 | 300.000000 | -0.0 | 2.986444e-300 | None | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584689e+07 | 2.684294e+07 | 1.099606e+07 | 0.0 | 7868.969315 | 0 | 0 | 0 | 1.647472e-04 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283825 | 1.284151 | 0.863122 | -5.059519e-09 | 0.000000 | 1.0 | 1.321226 | 3.14 | -0.032601 | -34712.323053 | 0 | 1.584689e+07 | 67812.972601 | 10000000.0 | None | 0 | 8 | 5 | 18 | 995 | NaN | 1.983318e+07 | 1.450026 | -1.000000e-07 | 1.000000e-05 | 1.45 | 1.251528 |
| 42786 | 769400 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3585600 | 2017-02-11 12:00:00 | 0 | 300.000000 | 0.0 | 1.493222e-300 | None | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584718e+07 | 2.684323e+07 | 1.099606e+07 | 0.0 | 7878.018836 | 0 | 0 | 0 | 1.647502e-04 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283778 | 1.284151 | 0.863107 | -5.068893e-09 | 0.000000 | 1.0 | 1.321178 | 3.14 | -0.032624 | -34686.405119 | 0 | 1.584718e+07 | 67811.741154 | 10000000.0 | None | 0 | 8 | 5 | 18 | 996 | NaN | 1.983318e+07 | 1.450026 | -1.000000e-07 | 1.000000e-05 | 1.45 | 1.251505 |
| 42787 | 769418 | {'cdp_count': 1, 'open_cdp_count': 1, 'closed_... | {} | {} | 3600 | 3589200 | 2017-02-11 13:00:00 | 0 | 300.000000 | 0.0 | 7.466109e-301 | open time locked drawn ... | 66110.592512 | 154827.528922 | 88716.936409 | 0.0 | 1.584747e+07 | 2.684352e+07 | 1.099606e+07 | 0.0 | 7887.068526 | 0 | 0 | 0 | 1.650584e-04 | 0.0 | 0.0 | 0.0 | 1.585490e-10 | 1.283732 | 1.284012 | 0.863091 | -5.068893e-09 | 0.000000 | 1.0 | 1.321130 | 3.14 | -0.032507 | -34660.235438 | 0 | 1.584747e+07 | 67810.507448 | 10000000.0 | <models.system_model_v3.model.parts.uniswap_or... | 0 | 8 | 5 | 18 | 997 | NaN | 1.983318e+07 | 1.450026 | -1.000000e-07 | 1.000000e-05 | 1.45 | 1.251482 |
42788 rows × 56 columns
%%capture
# Save the processed results to the same HDF5 store file
df.to_hdf(experiment_results, key=f'processed_results_{experiment_timestamp}')
from radcad.core import generate_parameter_sweep
param_sweep = generate_parameter_sweep(params)
df_control_parameters = df[['subset', 'kp', 'ki']]
df_control_parameters = df_control_parameters.drop_duplicates(subset=['kp', 'ki'])
df_control_parameters
| subset | kp | ki | |
|---|---|---|---|
| 0 | 0 | 1.000000e-07 | -1.000000e-09 |
| 998 | 1 | 1.000000e-07 | -1.000000e-08 |
| 1996 | 2 | 1.000000e-07 | -1.000000e-07 |
| 2994 | 3 | 1.000000e-06 | -1.000000e-09 |
| 3992 | 4 | 1.000000e-06 | -1.000000e-08 |
| 4990 | 5 | 1.000000e-06 | -1.000000e-07 |
| 5988 | 6 | 1.000000e-05 | -1.000000e-09 |
| 6986 | 7 | 1.000000e-05 | -1.000000e-08 |
| 7984 | 8 | 1.000000e-05 | -1.000000e-07 |
df.query('subset == 0')[['timestamp', 'eth_price', 'run']].plot(
title="ETH price shocks (positive and negative step and impulse; one shock type for each run)",
x='timestamp',
y='eth_price',
color='run'
)
fig = px.line(
df.query('run == 1'),
title="Price response for all control parameter subsets, first run",
x="timestamp",
y=["market_price", "market_price_twap", "target_price_scaled"],
facet_col="ki",
facet_row="kp",
height=1000
)
fig.show()
Get the initial target price to test stability conditions:
initial_target_price = df['target_price'].iloc[0]
initial_target_price
3.14
Find all controller constant subsets where the price goes to zero:
df_market_price_zero = df.query("market_price <= 0.1*@initial_target_price")
df_market_price_zero[['subset', 'kp', 'ki']].drop_duplicates(subset=['kp', 'ki'])
| subset | kp | ki |
|---|
Find all controller constant subsets where the price goes to infinity:
df_market_price_infinity = df.query("market_price > 10*@initial_target_price")
df_market_price_infinity[['subset', 'kp', 'ki']].drop_duplicates(subset=['kp', 'ki'])
| subset | kp | ki | |
|---|---|---|---|
| 19809 | 1 | 1.000000e-07 | -1.000000e-08 |
| 20447 | 2 | 1.000000e-07 | -1.000000e-07 |
| 23068 | 5 | 1.000000e-06 | -1.000000e-07 |
Create dataframe of stable simulation scenarios.
Stability is defined as:
df['stable_price'] = False
df.loc[df.eval("""
0.1*@initial_target_price < market_price <= 10*@initial_target_price and 0.1*@initial_target_price < target_price_scaled <= 10*@initial_target_price
"""), 'stable_price'] = True
df_stable_price = df.groupby("subset").filter(lambda x: all(x.query('timestep > 24*2')['stable_price'])) # and x['timestep'].max() == SIMULATION_TIMESTEPS
df_stable_price['subset'].unique()
array([0, 3, 4, 6, 7, 8])
fig = px.line(
df_stable_price.query('run == 1'),
title="Base case: Stable ETH price response",
x="timestamp",
y=["market_price", "market_price_twap", "target_price_scaled"],
facet_col="kp",
facet_row="ki",
facet_col_wrap=2,
height=1000
)
# fig.for_each_annotation(lambda a: a.update(text = f"kp={param_sweep[int(a.text.split('=')[-1])]['kp']} ki={param_sweep[int(a.text.split('=')[-1])]['ki']}"))
fig.show()
fig = px.line(
df_stable_price.query('run == 2'),
title="ETH price 30% step response",
x="timestamp",
y=["market_price", "market_price_twap", "target_price_scaled"],
facet_col="kp",
facet_row="ki",
facet_col_wrap=2,
height=1000
)
fig.show()
fig = px.line(
df_stable_price.query('run == 3'),
title="ETH price 30% impulse response",
x="timestamp",
y=["market_price", "market_price_twap", "target_price_scaled"],
facet_col="kp",
facet_row="ki",
facet_col_wrap=2,
height=1000
)
fig.show()
fig = px.line(
df_stable_price.query('run == 4'),
title="ETH price negative 30% step response",
x="timestamp",
y=["market_price", "market_price_twap", "target_price_scaled"],
facet_col="kp",
facet_row="ki",
facet_col_wrap=2,
height=1000
)
fig.show()
fig = px.line(
df_stable_price.query('run == 5'),
title="ETH price negative 30% impulse response",
x="timestamp",
y=["market_price", "market_price_twap", "target_price_scaled"],
facet_col="kp",
facet_row="ki",
facet_col_wrap=2,
height=1000
)
fig.show()
fig = px.line(
df_stable_price,
title="Reflexer principal debt",
x="timestamp",
y=["principal_debt"],
color='run',
facet_col="subset",
facet_col_wrap=4
)
fig.show()
fig = px.line(
df_stable_price,
title="Secondary market RAI balance",
x="timestamp",
y=["RAI_balance"],
color='run',
facet_col="subset",
facet_col_wrap=4
)
fig.show()
fig = px.line(
df_stable_price,
title="Reflexer ETH collateral",
x="timestamp",
y=["eth_collateral"],
color='run',
facet_col="subset",
facet_col_wrap=4
)
fig.show()
fig = px.line(
df_stable_price,
title="Secondary market ETH balance",
x="timestamp",
y=["ETH_balance"],
color='run',
facet_col="subset",
facet_col_wrap=4
)
fig.show()
df_stable_price.plot(
x='timestamp',
y=['collateralization_ratio'],
title='Collateralization ratio',
facet_col="subset",
)